package com.bf.electroplating.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bf.electroplating.pojo.dto.RainfallWeatherDataRequestDTO;
import com.bf.electroplating.pojo.dto.RainfallWeatherDataResponseDTO;
import com.bf.electroplating.pojo.entity.ComCompany;
import com.bf.electroplating.pojo.entity.RainfallOutletSite;
import com.bf.electroplating.pojo.entity.RainfallOutletWeatherData;
import com.bf.electroplating.service.IRainfallWeatherDataSyncService;
import com.bf.electroplating.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 雨排口天气数据同步服务实现类
 *
 * @author system
 * @since 2025-01-11
 */
@Slf4j
@Service
public class RainfallWeatherDataSyncServiceImpl implements IRainfallWeatherDataSyncService {


    @Autowired
    private com.bf.electroplating.service.IRainfallOutletSiteService rainfallOutletSiteService;

    @Autowired
    private com.bf.electroplating.service.IRainfallSiteListSyncService rainfallSiteListSyncService;

    @Autowired
    private com.bf.electroplating.service.IRainfallOutletWeatherDataService rainfallOutletWeatherDataService;

    @Value("${company.api.baseUrl}")
    private String apiBaseUrl;

    @Value("${company.api.secret}")
    private String apiSecret;

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public void syncAllRainfallWeatherData() {
        log.info("开始同步所有站点的雨排口天气数据");
        
        try {
            // 先同步站点列表，确保有最新的站点数据
            log.info("先同步雨排口站点列表数据");
            rainfallSiteListSyncService.syncRainfallSiteList();
            
            // 获取所有站点
            List<RainfallOutletSite> sites = rainfallOutletSiteService.list();
            
            if (sites.isEmpty()) {
                log.warn("没有找到雨排口站点，请检查站点列表同步是否成功");
                return;
            }

            // 为每个站点同步天气数据
            for (RainfallOutletSite site : sites) {
                try {
                    syncRainfallWeatherDataBySiteId(site.getSiteId());
                } catch (Exception e) {
                    log.error("同步站点 {} 的天气数据失败", site.getSiteName(), e);
                }
            }

            log.info("所有站点雨排口天气数据同步完成");
        } catch (Exception e) {
            log.error("同步所有站点雨排口天气数据失败", e);
        }
    }

    @Override
    public void syncRainfallWeatherDataBySiteId(Integer siteId) {
        log.info("开始同步站点 {} 的雨排口天气数据", siteId);
        
        try {
            // 获取最近7天的数据
            String endTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String beginTime = LocalDateTime.now().minusDays(7).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            
            syncRainfallWeatherDataByTimeRange(siteId, beginTime, endTime);
            
            log.info("站点 {} 的雨排口天气数据同步完成", siteId);
        } catch (Exception e) {
            log.error("同步站点 {} 的雨排口天气数据失败", siteId, e);
        }
    }

    @Override
    public void syncRainfallWeatherDataByTimeRange(Integer siteId, String beginTime, String endTime) {
        log.info("开始同步站点 {} 在 {} 到 {} 时间范围内的雨排口天气数据", siteId, beginTime, endTime);
        
        try {
            // 构建请求参数
            RainfallWeatherDataRequestDTO requestDTO = new RainfallWeatherDataRequestDTO();
            requestDTO.setSiteId(siteId);
            requestDTO.setBeginTime(beginTime);
            requestDTO.setEndTime(endTime);
            requestDTO.setMinutes(1);

            // 调用外部API
            String response = callRainfallWeatherDataAPI(requestDTO);
            
            // 解析响应数据
            RainfallWeatherDataResponseDTO responseDTO = JSON.parseObject(response, RainfallWeatherDataResponseDTO.class);
            
            if (responseDTO == null || !responseDTO.getSuccess() || responseDTO.getData() == null) {
                log.warn("站点 {} 的雨排口天气数据API返回失败或为空", siteId);
                return;
            }

            // 保存数据到数据库
            saveRainfallWeatherData(siteId, responseDTO.getData());
            
            log.info("站点 {} 在指定时间范围内的雨排口天气数据同步完成，共处理 {} 条数据", 
                    siteId, responseDTO.getData().size());
        } catch (Exception e) {
            log.error("同步站点 {} 在指定时间范围内的雨排口天气数据失败", siteId, e);
        }
    }

    @Override
    public void syncAllRainfallWeatherDataThisHour() {
        log.info("开始同步所有站点的雨排口天气数据");

        try {
            // 先同步站点列表，确保有最新的站点数据
            log.info("先同步雨排口站点列表数据");
            rainfallSiteListSyncService.syncRainfallSiteList();

            // 获取所有站点
            List<RainfallOutletSite> sites = rainfallOutletSiteService.list();

            if (sites.isEmpty()) {
                log.warn("没有找到雨排口站点，请检查站点列表同步是否成功");
                return;
            }

            // 为每个站点同步天气数据
            for (RainfallOutletSite site : sites) {
                try {
                    syncRainfallWeatherDataByTimeRange(site.getSiteId(),LocalDateTime.now().minusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
                            LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                } catch (Exception e) {
                    log.error("同步站点 {} 的天气数据失败", site.getSiteName(), e);
                }
            }

            log.info("所有站点雨排口天气数据同步完成");
        } catch (Exception e) {
            log.error("同步所有站点雨排口天气数据失败", e);
        }
    }

    /**
     * 调用雨排口天气数据API
     */
    private String callRainfallWeatherDataAPI(RainfallWeatherDataRequestDTO requestDTO) {
        try {
            String url = apiBaseUrl + "/out/site/data/list";
            
            // 使用签名工具类的加密方法
            String encryptedParams = SignUtil.generateParams(requestDTO);
            
            log.debug("调用雨排口天气数据API: {}, 参数: {}", url, encryptedParams);
            
            // 发送POST请求
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", "application/json");
            
            String response = restTemplate.postForObject(url, encryptedParams, String.class, headers);
            
            log.debug("雨排口天气数据API响应: {}", response);
            
            return response;
        } catch (Exception e) {
            log.error("调用雨排口天气数据API失败", e);
            throw new RuntimeException("调用雨排口天气数据API失败: " + e.getMessage());
        }
    }

    /**
     * 保存雨排口天气数据到数据库
     */
    private void saveRainfallWeatherData(Integer siteId, List<RainfallWeatherDataResponseDTO.WeatherDataItem> dataList) {
        if (dataList == null || dataList.isEmpty()) {
            return;
        }

        // 获取站点信息
        RainfallOutletSite site = rainfallOutletSiteService.getOne(
                new LambdaQueryWrapper<RainfallOutletSite>()
                        .eq(RainfallOutletSite::getSiteId, siteId)
        );

        String siteName = site != null ? site.getSiteName() : "未知站点";

        // 转换并保存数据
        List<RainfallOutletWeatherData> weatherDataList = dataList.stream().map(item -> {
            RainfallOutletWeatherData weatherData = new RainfallOutletWeatherData();
            weatherData.setSiteId(siteId);
            weatherData.setSiteName(siteName);
            
            // 解析时间
            try {
                LocalDateTime dataTime = LocalDateTime.parse(item.getMinute(), 
                        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                weatherData.setDataTime(dataTime);
            } catch (Exception e) {
                log.warn("解析时间失败: {}", item.getMinute());
                weatherData.setDataTime(LocalDateTime.now());
            }
            
            weatherData.setFactorValue(item.getFactorValue());
            weatherData.setRainAmount(item.getRain());
            weatherData.setMinutes(60);
            weatherData.setDelFlag("0");
            weatherData.setDataSource("API");
            weatherData.setIsValid(true);
            
            // 设置天气类型和名称
            String weather = item.getWeather();
            weatherData.setWeatherName(weather);
            
            // 根据天气名称设置天气类型
            if ("晴".equals(weather)) {
                weatherData.setWeatherType("1");
            } else if ("多云".equals(weather)) {
                weatherData.setWeatherType("2");
            } else if ("阴".equals(weather)) {
                weatherData.setWeatherType("3");
            } else if ("雨".equals(weather)) {
                weatherData.setWeatherType("4");
            } else if ("雪".equals(weather)) {
                weatherData.setWeatherType("5");
            } else {
                weatherData.setWeatherType("1"); // 默认为晴天
            }
            weatherData.setParkId("1001");
            return weatherData;
        }).collect(Collectors.toList());

        // 批量保存数据（使用upsert，避免重复数据）
        for (RainfallOutletWeatherData weatherData : weatherDataList) {
            try {
                // 检查是否已存在相同时间的数据
                RainfallOutletWeatherData existingData = rainfallOutletWeatherDataService.getOne(
                        new LambdaQueryWrapper<RainfallOutletWeatherData>()
                                .eq(RainfallOutletWeatherData::getSiteId, weatherData.getSiteId())
                                .eq(RainfallOutletWeatherData::getDataTime, weatherData.getDataTime())
                );

                if (existingData != null) {
                    // 更新现有数据
                    weatherData.setId(existingData.getId());
                    rainfallOutletWeatherDataService.updateById(weatherData);
                } else {
                    // 插入新数据
                    rainfallOutletWeatherDataService.save(weatherData);
                }
            } catch (Exception e) {
                log.error("保存雨排口天气数据失败: {}", weatherData, e);
            }
        }

        log.info("成功保存站点 {} 的 {} 条雨排口天气数据", siteId, weatherDataList.size());
    }
}
